package cn.colins.raft.rpc.session.defaults;

import cn.colins.raft.rpc.RpcRemoteContext;
import cn.colins.raft.rpc.domin.RpcRemoteMsg;
import cn.colins.raft.rpc.future.impl.SyncRpcWriteFuture;
import cn.colins.raft.rpc.session.RpcSession;
import cn.hutool.core.util.ReflectUtil;
import io.netty.channel.Channel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.UUID;
import java.util.concurrent.TimeoutException;

/**
 * @program: easy-rpc
 * @description: 默认的远程调用会话
 * @author: colins
 * @create: 2023-06-13 22:51
 **/
public class DefaultRpcSession<R, T> implements RpcSession<R, T> {
    private static final Logger log = LoggerFactory.getLogger(DefaultRpcSession.class);


    private T request;

    private final Channel channel;

    public DefaultRpcSession(Channel channel, T request) {
        this.channel = channel;
        this.request = request;
    }

    @Override
    public <R> R syncSend() {
        return syncSend(0L);
    }

    @Override
    public <R> R syncSend(long timeout) {
        String requestId = UUID.randomUUID().toString();
        SyncRpcWriteFuture syncRpcWriteFuture = new SyncRpcWriteFuture(requestId, timeout);
        Object write = null;
        try {
            write = syncRpcWriteFuture.write(channel, request);
            return (R) write;
        } catch (InterruptedException e) {
            log.error("接收中断：{}", e.getMessage(), e);
        } catch (Exception e) {
            log.error("接收异常：{}", e.getMessage(), e);
        } finally {
            RpcRemoteContext.removeRequestCache(requestId);
        }
        return null;
    }

    @Override
    public void asyncSend() {
        channel.writeAndFlush(new RpcRemoteMsg(request));
    }


}
